package org.example.sec11.respository;

import com.google.common.util.concurrent.Uninterruptibles;
import com.seaway.models.sec11.*;
import io.grpc.Status;
import io.grpc.stub.ServerCallStreamObserver;
import io.grpc.stub.StreamObserver;
import org.example.sec11.Constants;
import org.example.sec11.UserRole;

import java.util.concurrent.TimeUnit;

public class BankService extends BankServiceGrpc.BankServiceImplBase {

    @Override
    public void getAccountBalance(BalanceCheckRequest request, StreamObserver<AccountBalance> responseObserver) {
        sendAccountBalance(request, responseObserver);

    }

    private void sendAccountBalance(BalanceCheckRequest request, StreamObserver<AccountBalance> responseObserver) {
        var accountNumber = request.getAccountNumber();
        var balance = AccountRespository.getBalance(accountNumber);
        Uninterruptibles.sleepUninterruptibly(3, TimeUnit.SECONDS);
        if (Constants.USER_ROLE_KEY.get().equals(UserRole.STANDED)) {
            var fee = balance > 0 ? 1 : 0;
            AccountRespository.deductAccount(accountNumber, fee);
            balance = balance - fee;
        }
        var accountBalance = AccountBalance.newBuilder().setAccountNumber(accountNumber).setBalance(balance).build();

        responseObserver.onNext(accountBalance);
        responseObserver.onCompleted();
    }

    @Override
    public void withDraw(WithDrawRequest request, StreamObserver<Money> responseObserver) {
        //校验
        sendMoney(request, responseObserver);
    }

    private void sendMoney(WithDrawRequest request, StreamObserver<Money> responseObserver) {
        try {
            int accountNumber = request.getAccountNumber();
            int amount = request.getAmount();
            for (int i = 0; i < (amount / 10); i++) {
                var money = Money.newBuilder().setAmount(10).build();
                responseObserver.onNext(money);
                AccountRespository.deductAccount(accountNumber, 10);
                Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
            }
            responseObserver.onCompleted();
        } catch (Exception e) {
            responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).getCause());
        }
    }

}
